/***************************************************************************
 *            protocol.c
 *
 *  Fri Dec  4 11:13:03 2009
 *  Copyright  2009  simone vellei
 *  <henomis@gmail.com>
 ****************************************************************************/

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */

#include <string.h>
#include <stdio.h>
#include "protocol.h"
#include "sha1.h"
#include "rand.h"



void init_packet(packet_t *pkt, unsigned char *key)
{
	SHA1_CTX context;
	
	SHA1Init(&context);
	SHA1Update(&context, (unsigned char*)key, strlen((char*)key));
	SHA1Final(pkt->key, &context);
}


void prepare_packet(packet_t *pkt, unsigned char header, unsigned char command, unsigned char doprng, unsigned int prng)
{
	// 2 byte command
	// 4 byte prng number
	// 20 shared key 
	unsigned char buffer[26];
	SHA1_CTX context;
	unsigned int random_number;

	if(doprng == 1)
		random_number = HX_rand();			
	else
		random_number = prng;

	memset(buffer,0, 26);

	pkt->data.field.header = header;
	pkt->data.field.command = command;
	pkt->data.field.notused = command; //not used for now!
	pkt->data.field.seqnum  = random_number;


	memcpy(&buffer[0], &pkt->data.field.command, 2);
	memcpy(&buffer[2], &pkt->data.field.seqnum, 4);
	memcpy(&buffer[6], pkt->key, 20);

	SHA1Init(&context);
	SHA1Update(&context, buffer, 26);
	SHA1Final(pkt->data.field.armor, &context);
/*	printf("prepare_packet()\n");
		info_packet (pkt);*/
}

unsigned char check_packet(packet_t *pkt, unsigned char *key, unsigned int last_seqnum)
{
	int ret = 0;

	packet_t pkg_tmp;

	/*printf("check_packet1()\n");
	info_packet (pkt);*/
	
	init_packet(&pkg_tmp, key);
	prepare_packet(&pkg_tmp, pkt->data.field.header, pkt->data.field.command, 0, last_seqnum);

/*	printf("check_packet2()\n");
	info_packet (&pkg_tmp);*/

	if (memcmp(pkg_tmp.data.field.armor, pkt->data.field.armor, 20) != 0) 
		ret = 1;

	return ret;

}


void info_packet(packet_t *pkt)
{
	int i,j; 

	printf("KEY:\t[");
	
	for (i = 0; i < 5; i++) {
		for (j = 0; j < 4; j++) {
			printf("%02X", pkt->key[i*4+j]);
		}
	}
	printf("]\n");
	printf("HEADER:\t[%.2x]\n", pkt->data.field.header);
	printf("COMMAND:\t[%.2x]\n", pkt->data.field.command);
	printf("NOTUSED:\t[%.2x]\n", pkt->data.field.notused);
	printf("SEQNUM:\t[%d]\n", pkt->data.field.seqnum);
	printf("ARMOR:\t[");
	
	for (i = 0; i < 5; i++) {
		for (j = 0; j < 4; j++) {
			printf("%02X", pkt->data.field.armor[i*4+j]);
		}
	}
	printf("]\n\n");
}





